import Foundation

class TraceUploader {
    private let session = URLSession.shared
    private var timer: Timer?
    private let storage: TraceStorage
    
    init(storage: TraceStorage) {
        self.storage = storage
        setupTimer()
        setupNotifications()
    }
    
    deinit {
        timer?.invalidate()
        NotificationCenter.default.removeObserver(self)
    }
    
    private func setupTimer() {
        let interval = TraceManager.shared.config.uploadStrategy.interval
        timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(uploadEvents), userInfo: nil, repeats: true)
    }
    
    private func setupNotifications() {
        if TraceManager.shared.config.uploadStrategy.uploadWhenAppEnterBackground {
            NotificationCenter.default.addObserver(
                self,
                selector: #selector(applicationDidEnterBackground),
                name: UIApplication.didEnterBackgroundNotification,
                object: nil
            )
        }
    }
    
    @objc private func applicationDidEnterBackground() {
        uploadEvents()
    }
    
    @objc func uploadEvents() {
        let events = storage.loadEvents()
        if events.isEmpty {
            return
        }
        
        let threshold = TraceManager.shared.config.uploadStrategy.threshold
        if events.count < threshold && UIApplication.shared.applicationState != .background {
            return
        }
        
        upload(events: events)
    }
    
    func upload(events: [TraceEvent]) {
        guard !events.isEmpty else { return }
        guard let url = URL(string: TraceManager.shared.config.serverURL) else { return }
        
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        
        do {
            let jsonData = try JSONEncoder().encode(events)
            request.httpBody = jsonData
            
            let task = session.dataTask(with: request) { [weak self] data, response, error in
                guard let self = self else { return }
                
                if let error = error {
                    print("Failed to upload trace events: \(error)")
                    return
                }
                
                guard let httpResponse = response as? HTTPURLResponse else {
                    print("Invalid response")
                    return
                }
                
                if (200...299).contains(httpResponse.statusCode) {
                    // 上传成功，删除已上传的事件
                    self.storage.removeEvents(events)
                } else {
                    print("Upload failed with status code: \(httpResponse.statusCode)")
                }
            }
            
            task.resume()
        } catch {
            print("Failed to encode trace events: \(error)")
        }
    }
}